<template>
  <div class="date-picker-container" v-if="visible">
    <!-- 遮罩层 -->
    <div 
      class="date-picker__mask" 
      @click="handleCancel"
      :style="{ backgroundColor: maskColor }"
    ></div>

    <!-- 选择器主体 -->
    <div 
      class="date-picker__wrapper"
      :style="{ 
        width: wrapperWidth, 
        borderRadius: borderRadius,
        backgroundColor: wrapperBgColor 
      }"
    >
      <!-- 操作栏 -->
      <div class="date-picker__header" :style="{ borderBottomColor: headerBorderColor }">
        <span 
          class="date-picker__btn date-picker__btn--cancel" 
          @click="handleCancel"
          :style="{ color: cancelTextColor, fontSize: btnFontSize }"
          :class="{ 'date-picker__btn--disabled': disabled }"
        >
          {{ cancelText }}
        </span>
        <h3 
          class="date-picker__title"
          :style="{ color: titleColor, fontSize: titleFontSize, fontWeight: titleFontWeight }"
        >
          {{ title }}
        </h3>
        <span 
          class="date-picker__btn date-picker__btn--confirm" 
          @click="handleConfirm"
          :style="{ color: confirmTextColor, fontSize: btnFontSize }"
          :class="{ 'date-picker__btn--disabled': disabled || !isValidDate }"
        >
          {{ confirmText }}
        </span>
      </div>

      <!-- 日期选择器：确保数据就绪后渲染 -->
      <picker-view 
        v-if="years.length > 0 && displayedDays.length > 0 && isIndicatorStyleValid"
        :value="currentPickerValue" 
        @change="onPickerChange" 
        :indicator-style="indicatorStyleStr"
        :key="pickerKey"
        :style="{ height: pickerHeight }"
        :disabled="disabled"
      >
        <picker-view-column>
          <div 
            v-for="year in years" 
            :key="year" 
            class="date-picker__item" 
            :style="{ fontSize: itemFontSize }"
          >
            {{ year }}年
          </div>
        </picker-view-column>
        <picker-view-column>
          <div 
            v-for="month in months" 
            :key="month" 
            class="date-picker__item" 
            :style="{ fontSize: itemFontSize }"
          >
            {{ month }}月
          </div>
        </picker-view-column>
        <picker-view-column>
          <div 
            v-for="day in displayedDays" 
            :key="day" 
            class="date-picker__item" 
            :style="{ fontSize: itemFontSize }"
          >
            {{ day }}日
          </div>
        </picker-view-column>
      </picker-view>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onBeforeUnmount } from 'vue'

// ------------------------------ 类型定义 ------------------------------
interface DateObj {
  year: number
  month: number
  day: number
}

interface DatePickerProps {
  visible: boolean
  minDate?: string
  maxDate?: string
  defaultDate?: string
  disabled?: boolean
  title?: string
  cancelText?: string
  confirmText?: string
  format?: 'YYYY-MM-DD'
  maskColor?: string
  wrapperWidth?: string
  wrapperBgColor?: string
  borderRadius?: string
  headerBorderColor?: string
  titleColor?: string
  titleFontSize?: string
  titleFontWeight?: string
  cancelTextColor?: string
  confirmTextColor?: string
  btnFontSize?: string
  pickerHeight?: string
  indicatorHeight?: string
  itemFontSize?: string
}

// ------------------------------ Props与默认值 ------------------------------
const props = withDefaults(defineProps<DatePickerProps>(), {
  minDate: '1900-01-01',
  maxDate: '2099-12-31',
  defaultDate: '',
  disabled: false,
  title: '选择日期',
  cancelText: '取消',
  confirmText: '确认',
  format: 'YYYY-MM-DD',
  maskColor: 'rgba(0, 0, 0, 0.5)',
  wrapperWidth: '90%',
  wrapperBgColor: '#fff',
  borderRadius: '16px',
  headerBorderColor: '#eee',
  titleColor: '#333',
  titleFontSize: '18px',
  titleFontWeight: '600',
  cancelTextColor: '#00897B',
  confirmTextColor: '#00897B',
  btnFontSize: '16px',
  pickerHeight: '250px',
  indicatorHeight: '50px',
  itemFontSize: '16px'
})

// ------------------------------ 事件定义 ------------------------------
const emit = defineEmits<{
  (e: 'confirm', value: string): void
  (e: 'cancel'): void
}>()

// ------------------------------ 响应式数据 ------------------------------
const currentPickerValue = ref<number[]>([0, 0, 0]) // 确保初始为长度3的数组
const pickerKey = ref(0)
const years = ref<number[]>([])
const months = ref<number[]>(Array.from({ length: 12 }, (_, i) => i + 1)) // 固定1-12月
const displayedDays = ref<number[]>([])
const debounceTimer = ref<NodeJS.Timeout | null>(null)

// ------------------------------ 计算属性 ------------------------------
const isIndicatorStyleValid = computed<boolean>(() => {
  return /^(\d+(\.\d+)?)(px|rem|em)?$/.test(props.indicatorHeight)
})

const indicatorStyleStr = computed<string>(() => {
  const safeHeight = props.indicatorHeight.replace(/[<>!-]/g, '')
  if (!/px|rem|em$/.test(safeHeight) && safeHeight !== '') {
    return `height: ${safeHeight}px;`
  }
  return `height: ${safeHeight};`
})

const minDateObj = computed<DateObj>(() => {
  const [year, month, day] = props.minDate.split('-').map(Number)
  return { year, month, day }
})

const maxDateObj = computed<DateObj>(() => {
  const [year, month, day] = props.maxDate.split('-').map(Number)
  return { year, month, day }
})

// 修复：严格检查数组长度和索引有效性
const selectedYear = computed<number>(() => {
  if (
    !Array.isArray(currentPickerValue.value) || 
    currentPickerValue.value.length < 1 ||
    !Array.isArray(years.value) ||
    years.value.length === 0 ||
    currentPickerValue.value[0] < 0 ||
    currentPickerValue.value[0] >= years.value.length
  ) {
    return 0
  }
  return years.value[currentPickerValue.value[0]] || 0
})

const selectedMonth = computed<number>(() => {
  if (
    !Array.isArray(currentPickerValue.value) || 
    currentPickerValue.value.length < 2 ||
    !Array.isArray(months.value) ||
    months.value.length === 0 ||
    currentPickerValue.value[1] < 0 ||
    currentPickerValue.value[1] >= months.value.length
  ) {
    return 0
  }
  return months.value[currentPickerValue.value[1]] || 0
})

const selectedDay = computed<number>(() => {
  if (
    !Array.isArray(currentPickerValue.value) || 
    currentPickerValue.value.length < 3 ||
    !Array.isArray(displayedDays.value) ||
    displayedDays.value.length === 0 ||
    currentPickerValue.value[2] < 0 ||
    currentPickerValue.value[2] >= displayedDays.value.length
  ) {
    return 0
  }
  return displayedDays.value[currentPickerValue.value[2]] || 0
})

const isValidDate = computed<boolean>(() => {
  return selectedYear.value > 0 && selectedMonth.value > 0 && selectedDay.value > 0
})

const formattedSelectedDate = computed<string>(() => {
  if (!isValidDate.value) return ''
  const year = selectedYear.value
  const month = String(selectedMonth.value).padStart(2, '0')
  const day = String(selectedDay.value).padStart(2, '0')
  return `${year}-${month}-${day}`
})

// ------------------------------ 核心方法 ------------------------------
const parseDate = (dateStr: string): DateObj => {
  if (!/^\d{4}-\d{2}-\d{2}$/.test(dateStr)) {
    console.error(`DatePicker 错误：日期格式无效（${dateStr}），需符合YYYY-MM-DD`)
    return { year: 0, month: 0, day: 0 }
  }
  const [year, month, day] = dateStr.split('-').map(Number)
  return { year, month, day }
}

const getValidDate = (dateStr: string): string => {
  const date = parseDate(dateStr)
  const min = minDateObj.value
  const max = maxDateObj.value

  if (
    date.year < min.year ||
    (date.year === min.year && date.month < min.month) ||
    (date.year === min.year && date.month === min.month && date.day < min.day)
  ) {
    return props.minDate
  }

  if (
    date.year > max.year ||
    (date.year === max.year && date.month > max.month) ||
    (date.year === max.year && date.month === max.month && date.day > max.day)
  ) {
    return props.maxDate
  }

  return dateStr
}

const initYears = () => {
  const minYear = minDateObj.value.year
  const maxYear = maxDateObj.value.year
  if (minYear > maxYear) {
    console.error('DatePicker 错误：minDate年份不能大于maxDate年份')
    years.value = []
    return
  }
  years.value = Array.from({ length: maxYear - minYear + 1 }, (_, i) => minYear + i)
}

const getDaysInMonth = (year: number, month: number): number => {
  return new Date(year, month, 0).getDate()
}

const getDayRange = (year: number, month: number): { startDay: number; endDay: number } => {
  let startDay = 1
  let endDay = getDaysInMonth(year, month)

  if (year === minDateObj.value.year && month === minDateObj.value.month) {
    startDay = minDateObj.value.day
  }
  if (year === maxDateObj.value.year && month === maxDateObj.value.month) {
    endDay = maxDateObj.value.day
  }

  return { startDay: Math.min(startDay, endDay), endDay: Math.max(startDay, endDay) }
}

const updateDisplayedDays = (year: number, month: number) => {
  // 修复：校验年和月的有效性
  if (!year || !month) return

  if (debounceTimer.value) clearTimeout(debounceTimer.value)
  debounceTimer.value = setTimeout(() => {
    const { startDay, endDay } = getDayRange(year, month)
    displayedDays.value = Array.from({ length: endDay - startDay + 1 }, (_, i) => startDay + i)
    
    // 修复：确保currentPickerValue有效
    if (
      Array.isArray(currentPickerValue.value) && 
      currentPickerValue.value.length >= 3 &&
      displayedDays.value.length > 0
    ) {
      // 限制日索引在有效范围内
      const validDayIndex = Math.min(
        Math.max(0, currentPickerValue.value[2]), 
        displayedDays.value.length - 1
      )
      currentPickerValue.value = [
        currentPickerValue.value[0],
        currentPickerValue.value[1],
        validDayIndex
      ]
    }
  }, 30)
}

const scrollToDate = (dateStr: string) => {
  const validDateStr = getValidDate(dateStr)
  const targetDate = parseDate(validDateStr)
  if (targetDate.year === 0 || targetDate.month === 0 || targetDate.day === 0) return

  if (years.value.length === 0) initYears()
  if (years.value.length === 0) return // 年份初始化失败则退出

  // 修复：查找有效年份索引
  const yearIndex = years.value.indexOf(targetDate.year)
  if (yearIndex === -1) return

  // 修复：确保月份索引有效
  const monthIndex = targetDate.month - 1
  if (monthIndex < 0 || monthIndex >= 12) return

  updateDisplayedDays(targetDate.year, targetDate.month)

  setTimeout(() => {
    if (displayedDays.value.length === 0) return

    // 修复：查找有效日期索引
    const dayIndex = displayedDays.value.indexOf(targetDate.day)
    const validDayIndex = dayIndex !== -1 ? dayIndex : 0

    currentPickerValue.value = [yearIndex, monthIndex, validDayIndex]
    pickerKey.value++
  }, 0)
}

const initData = () => {
  initYears()
  if (years.value.length === 0) {
    console.error('DatePicker 初始化失败：年份列表为空')
    return
  }

  if (props.defaultDate) {
    scrollToDate(props.defaultDate)
  } else {
    const today = new Date()
    const todayStr = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, '0')}-${String(today.getDate()).padStart(2, '0')}`
    scrollToDate(getValidDate(todayStr))
  }
}

// ------------------------------ 事件处理：核心错误修复 ------------------------------
const onPickerChange = (e: { target: { value: number[] } }) => {
  if (props.disabled) return
  const newValue = e.target.value

  // 修复：严格校验newValue的有效性
  if (
    !Array.isArray(newValue) || 
    newValue.length < 3 ||
    years.value.length === 0 ||
    months.value.length === 0 ||
    displayedDays.value.length === 0
  ) {
    return
  }

  // 修复：确保索引在有效范围内
  const validYearIndex = Math.min(Math.max(0, newValue[0]), years.value.length - 1)
  const validMonthIndex = Math.min(Math.max(0, newValue[1]), months.value.length - 1)
  const validDayIndex = Math.min(Math.max(0, newValue[2]), displayedDays.value.length - 1)
  const safeNewValue = [validYearIndex, validMonthIndex, validDayIndex]

  const oldValue = [...currentPickerValue.value]
  currentPickerValue.value = safeNewValue

  const yearChanged = oldValue[0] !== safeNewValue[0]
  const monthChanged = oldValue[1] !== safeNewValue[1]
  if (yearChanged || monthChanged) {
    // 修复：确保年份和月份存在
    const year = years.value[safeNewValue[0]]
    const month = months.value[safeNewValue[1]]
    if (year && month) { // 只有当年月有效时才更新日期
      updateDisplayedDays(year, month)
    }
  }
}

const handleCancel = () => {
  if (props.disabled) return
  emit('cancel')
}

const handleConfirm = () => {
  if (props.disabled || !isValidDate.value) return
  emit('confirm', formattedSelectedDate.value)
}

// ------------------------------ 生命周期 ------------------------------
watch(() => props.visible, (isVisible) => {
  if (isVisible) {
    // 确保currentPickerValue始终是长度为3的数组
    if (!Array.isArray(currentPickerValue.value) || currentPickerValue.value.length !== 3) {
      currentPickerValue.value = [0, 0, 0]
    }
    initData()
  }
}, { immediate: true })

watch(() => props.defaultDate, (newVal) => {
  if (props.visible && newVal && years.value.length > 0) {
    scrollToDate(newVal)
  }
})

watch(() => props.indicatorHeight, () => {
  if (!isIndicatorStyleValid.value) {
    console.warn('DatePicker 警告：indicatorHeight值无效，已自动修正为默认值')
  }
})

onBeforeUnmount(() => {
  if (debounceTimer.value) clearTimeout(debounceTimer.value)
})
</script>

<style scoped lang="scss">
$prefix: date-picker;
$animation-duration: 0.3s;
$header-padding: 16px;
$item-height: 50px;

.#{$prefix}-container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  z-index: 999;
  display: flex;
  justify-content: center;
  align-items: center;
}

.#{$prefix}__mask {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  transition: background-color $animation-duration;
}

.#{$prefix}__wrapper {
  overflow: hidden;
  max-width: 400px;
  position: relative;
  z-index: 1000;
  animation: fadeIn $animation-duration ease-out;
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: scale(0.95);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

.#{$prefix}__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: $header-padding;
  border-bottom: 1px solid;
  transition: border-bottom-color $animation-duration;

  .#{$prefix}__btn {
    cursor: pointer;
    transition: color $animation-duration, opacity $animation-duration;

    &--disabled {
      opacity: 0.6;
      pointer-events: none;
    }
  }

  .#{$prefix}__btn--cancel {
    margin-right: auto;
  }

  .#{$prefix}__btn--confirm {
    margin-left: auto;
  }

  .#{$prefix}__title {
    font-size: inherit;
    font-weight: inherit;
    color: inherit;
    transition: color $animation-duration, font-size $animation-duration;
  }
}

picker-view {
  height: inherit;
  transition: height $animation-duration;
}

.#{$prefix}__item {
  display: flex;
  align-items: center;
  justify-content: center;
  height: $item-height;
  text-align: center;
  color: #333;
  transition: font-size $animation-duration, color $animation-duration;
}
</style>
